<?

/*
 * This collection of functions (library) is licensed under GPL2.
 * See LICENSE or www.gnu.org for more details.
 */


define(DZ_SESSIONTABLE, "dzsessions");
define(DZ_SES_COL_USERID, DZ_SESSIONTABLE.".userid");
define(DZ_SES_COL_STARTED, DZ_SESSIONTABLE.".started");
define(DZ_SES_COL_ID, DZ_SESSIONTABLE.".id");
define(DZ_SES_COL_ACCESSED, DZ_SESSIONTABLE.".accessed");

include_once("sosqlhi.php");
include_once("sostring.php");
include_once("sodatetime.php");

/** class dzSesam
 *  Dataz session administration tool
 *  
 *  constructor takes one parameter: 
 *    $AccessStr that contains "host dbname user password" 
 *    to access session table
 *  
 *  getSessions($UserId) - Gets the list of user's open session in an array
 *  addSession($UserId) - Adds an session for the user in the session table.
 *                        Created session ID is returned.
 *  delSession($Id) - Deletes the given session from the session table
 *  createTable() - Creates the session ID table.
 */
class dzSesam {

    /* private properties */
    var $__Soda;         /* global soBaSQL object */

    /** constructor
     *  Initialize properties and check that the session table exist.
     *  If not create it.
     *  @param object $DbObj PEAR:DB object
     *  @param array/any DB options
     */
    function dzSesam(&$DbObj, $Options = array()) {
        soDebug("dzSesam->constructor", SOD_DET);
        $this->__Soda = new soDa($DbObj, $Options);
        $this->__Soda->setTable(DZ_SESSIONTABLE);
    } // dzsesam

    
    /** Look up for user's open sessions.
     *
     * >$UserID:str User name of the user whose sessions look for
     * <:array users sessions IDs, If nothing is found an empty
     *         array is returned
     */
    function getSessions($UserID) {
        if ($UserID) {
            soDebug("dzSesam->getSessions", SOD_DET);
        } else {
            soDebug("dzSesam->getSessions - no user!", SOD_LO);
            return array(); // <-- EXIT on error
        };

        $result = array();
        $this->__Soda->setAction(SODA_SELECT);
        $this->__Soda->setSection(SODA_DATA, DZ_SES_COL_USERID." ".
                                  DZ_SES_COL_STARTED." ".
                                  DZ_SES_COL_ID." ".
                                  DZ_SES_COL_ACCESSED, array());
        $this->__Soda->setSection(SODA_WHERE, DZ_SES_COL_USERID,
                                  array($UserID));
        if ($this->__Soda->run()) {
            $icount = $this->__Soda->Results->count();
            for ($i = 0; $i < $icount; $i++) {
                $result[] = array(
                    $this->__Soda->Results->getValue(DZ_SES_COL_USERID, $i),
                    $this->__Soda->Results->getValue(DZ_SES_COL_STARTED, $i),
                    $this->__Soda->Results->getValue(DZ_SES_COL_ID, $i),
                    $this->__Soda->Results->getValue(DZ_SES_COL_ACCESSED, $i)
                                 );
            }; // if
        } else {
            /* Error try to create the session table */
            $this->createTable();
            /* No table no sessions. Return an empty table */
        } // if ($this->__Soda->run())

        return $result;
    } // getSessions


    /** Create new session for user.
        Creates a new session id and writes it to session table for
        user.

        Session id is in form of "timestamp_precision" where
        'timestamp' is unix timestamp in seconds and 'precision'
        is 0 by default or 1 if 0 was used, or 2 if 1 was used etc.

        >$UserID:str User name who will own the session
        <:str session id. An empty string is returned in case of an error
    */
    function addSession($UserID) {
        $now = soTime();

        /* Created is unix timestamp, so precision number must be
           used to separate id's created within the same second.
           That is done by using $precision, that is incremented
           one by one when insert fails. */
        $precision = 0;
        do {
            /* Get the timestamp and use it as a part of the sesion id. */
            $id = time().$precision;

            $this->__Soda->setAction(SODA_INSERT);
            $this->__Soda->flushCache();
            $this->__Soda->setSection(SODA_DATA, DZ_SES_COL_ID." ".
                                      DZ_SES_COL_USERID." ".
                                      DZ_SES_COL_STARTED.":datetime ".
                                      DZ_SES_COL_ACCESSED.":datetime",
                                      array($id, $UserID, $now, $now));

            if (!$this->__Soda->run()) {
                /* Session id already exists */
                $result = "";
                $precision++;
            } else {
                /* This id unique -> ok */
                $result = $id;
            }; // if results->count
        } while (!$result);

        return $result;
    } // addSession


    /** Remove session ID from the session table
     *
     * >$Id:str Session Id
     * <:bool   true on success otherwise false
     */
    function delSession($Id) {
        $this->__Soda->setAction(SODA_DELETE);
        $this->__Soda->flushCache();
        $this->__Soda->setSection(SODA_WHERE, "id", array($Id));

        if ($this->__Soda->run()) {
            $result = true;
        } else {
            $result = false;
        };

        return $result;
    } // delSession


    /** update the sessions access time
     *
     * >$Id:str Session Id
     * <:bool   true on success otherwise false
     */
    function updAccessTime($Id) {
        soDebug("dzSesam->updAccessTime()", SOD_DET);
        $result = true;
        $this->__Soda->setAction(SODA_UPDATE);
        $this->__Soda->flushCache();
        $this->__Soda->setSection(SODA_WHERE, DZ_SES_COL_ID, array($Id));
        $this->__Soda->setSection(SODA_DATA, DZ_SES_COL_ACCESSED.":dt",
                                  array(soTime()));
        if ($this->__Soda->run()) {
            $result = true;
        } else {
            $result = false;
        };

        return $result;
    } // updAccessTime

    /** createTable()
     *  Creates a session table, returns != 0 on error
     */
    function createTable() {
        soDebug("dzSesam->createTable()", SOD_DET);
        $this->__Soda->setAction(SODA_CREATE);
        $this->__Soda->setSection(SODA_DATA, "id userid started accessed *",
                                  array("char(40) not null", "char(12)",
                                        "timestamp", "timestamp", "id"));
        $result = $this->__Soda->run();

    return $result;
    } // createTable


    /** Gets the session owner if session exists
     *  Checks is the given session id exist. If it does, return the owner,
     *  otherwise "" (null string).
     */
    function getSesOwner($Id) {
        $this->__Soda->setAction(SODA_SELECT);
        $this->__Soda->setSection(SODA_DATA, DZ_SES_COL_USERID, array());
        $this->__Soda->setSection(SODA_WHERE, DZ_SES_COL_ID, array($Id));
        if ($this->__Soda->run()) {
            if ($this->__Soda->Results->count() < 1) {
                $result = NULL;
            } else {
                $result = $this->__Soda->Results->getValue(DZ_SES_COL_USERID);
            }
        } else {
            $result = "";
        }; // if sql->run

        return $result;
    } // getSesOwner


    /** isOwner()
     *  Check is the given user is the owner of the given session id.
     *  returns true if is otherwise returns false
     */
    function isOwner($Username, $Id) {
        if ($this->getSesOwner($Id) == $Username) {
            return true;
        } else {
            return false;
        }
    } // isOwner


} // class dzSesam

?>
